/*************************************************************************
*																		 *
*				code by Miles Chen (v-mich) 2007.10.8					 *
*																		 *
*																		 *
*************************************************************************/

#pragma once

namespace Noria{

	typedef const LRESULT 
		(WINAPI *SendMessageNextW)(
		__in HWND hWnd,
		__in UINT Msg,
		__in WPARAM wParam,
		__in LPARAM lParam);
	//
	typedef struct _PAYLOAD
	{
		HWND	hWnd;
		WCHAR	lpBuffer[MAX_CHAR];
		LRESULT lpResult;
		SendMessageNextW lpProcSendMessageW;

	}PAYLOAD, *LPPAYLOAD;
	//

	class CSpyCab sealed
	{
	public:
		CSpyCab(void);
		~CSpyCab(void);


	public:
		HWND m_hWndCurrent;

	private:
		int m_nIDC_SPY_HWND;
		int m_nIDC_SPY_PID;
		int m_nIDC_SPY_ID;
		int m_nIDC_SPY_CAPTION;
		int m_nIDC_SPY_CLASS;
		int m_nIDC_SPY;

	private:

		//stack to save temp window handles
		HWND* m_pWnd;
		int m_stackPointer;

		HCURSOR m_hCursorSpy, m_hCursorOriginal;
		WCHAR m_szBuffer[MAX_CHAR];
		HWND m_hDlg;
		DWORD m_dwProcID;
		HANDLE m_hProc;
		HANDLE m_hThread;
		LPVOID m_lpRemoteExecute;
		LPPAYLOAD m_lpPayload;
		PAYLOAD m_payload;
		DWORD m_dwResult;

		HDC m_hdc;
		RECT m_rect;
		HPEN m_hPen;
		HPEN m_hPrevPen;
		HBRUSH m_hBrush;
		HBRUSH m_hPrevBrush;

		BOOL m_fIsSearch;
		HWND m_hPreWnd;
		POINT m_point;

		HWND m_hWndBestFound, m_hWndSearch, m_hWndTemp;
		UINT m_uSmallestWindowSquare, m_uCurrentWindowSquare;
		RECT m_rectTemp;

	public:
		int InitSpy(HWND hDlg, HCURSOR hCursor, int, int, int, int, int, int);
		int OnSpyStart();
		int OnSpyFinish();
		int OnSpySearching();

	private:
		BOOL ValidateWindow();
		BOOL EnumChildWindowsEx();
		int PreciseSearch();
		BOOL RemoteGetPasswordEditText(HWND hEdit);
		BOOL HighlightFoundWindow(HWND hWnd);
		BOOL RefreshWindow(HWND hWnd);
		static LRESULT __stdcall RemoteExecute(LPPAYLOAD p);
	};
}
